package wortubung.inflection;

import static wortubung.util.CommonUtils.*;

import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import wortubung.core.LANG;

public class PrefixMatcher {

	public static class Match {
		public String prefix;
		public String rest;
		public PrefixType type;
		
		public boolean isSeparable() { return type == PrefixType.GERMAN_SEPARABLE; }
	}

	private LANG lang;
	private Pattern pattern;
	private Pattern fauxPattern;
	private HashMap<String,PrefixType> types; // only for German so far

	public PrefixMatcher(LANG lang, List<String> prefices, List<String> fauxPrefices) {
		this.lang = lang;

		StringBuilder sb = new StringBuilder("^(");
		if (isNotEmpty(fauxPrefices)) {
			sortByLength(fauxPrefices);
			for (String fp : fauxPrefices) {
				if (sb.length() > 2)
					sb.append('|');
				sb.append(fp);
			}
			fauxPattern = Pattern.compile(sb.append(")").toString());
		}

		sb.setLength(2);
		boolean isDeutsch = (lang == LANG.de);
		if (isDeutsch)
			types = new HashMap<String,PrefixType>();
		sortByLength(prefices);
		for (String pref : prefices) {
			if (isDeutsch) {
				PrefixType type = PrefixType.GERMAN_DUAL;
				int toChop = 0;
				if (pref.endsWith("|")) {
					type = PrefixType.GERMAN_SEPARABLE;
					toChop = 1;
				}
				else if (pref.endsWith("+")) {
					type = PrefixType.GERMAN_INSEPARABLE;
					toChop = 1;
				}
				else if (pref.endsWith("?")) {
					toChop = 1;
				}
				if (toChop > 0)
					pref = chopRight(pref, toChop);
				types.put(pref, type);
			}

			if (sb.length() > 2)
				sb.append('|');
			sb.append(pref);
		}
		pattern = Pattern.compile(sb.append(")").toString());
	}

	public Match match(String word) {
		if (fauxPattern != null && fauxPattern.matcher(word).find())
			return null;
		Matcher matcher = pattern.matcher(word);
		if (!matcher.find())
			return null;
		Match ret = new Match();
		ret.prefix = matcher.group();
		ret.rest = word.substring(ret.prefix.length());
		if (lang == LANG.de)
			ret.type = types.get(ret.prefix);
		return ret;
	}
}
